package com.pan.kang.dao.impl;

import com.pan.kang.util.ConvertUtil;
import com.pan.kang.util.DBUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class AccComprehensiveQueryConvertSqlDao {
    public static String QT_INSERT_STA_CUR_FIELD = ",TWBMONEYF,\nTNUM1F,\nSUM_SL_D,\nSUM_SL_DL,\nSUM_D_HL,\nQMYE_HL";
    public static String QT_SELECT_STA_CUR_FIELD = ",SUM(TWBMONEYF) TWBMONEYF,\nSUM(TNUM1F) TNUM1F,\nSUM(SUM_SL_D) SUM_SL_D,\nSUM(SUM_SL_DL) SUM_SL_DL,\nSUM(SUM_D_HL) SUM_D_HL,\nSUM(QMYE_HL) QMYE_HL";
    public static String QT_INSERT_FOR_CUR_FIELD = "TMONEYF,\nTWBMONEYF,\nNUMSCALEF,\nTNUM1F,\nSUM_SL_J,\nSUM_SL_D,\nSUM_SL_JL,\nSUM_SL_DL,\nSUM_J_HL,\nSUM_D_HL,\nQCYE_HL,\nQMYE_HL";
    public static String QT_SELECT_FOR_CUR_FIELD = "SUM(TMONEYF) TMONEYF,\nSUM(TWBMONEYF) TWBMONEYF,\nSUM(NUMSCALEF) NUMSCALEF,\nSUM(TNUM1F) TNUM1F,\nSUM(SUM_SL_J) SUM_SL_J,\nSUM(SUM_SL_D) SUM_SL_D,\nSUM(SUM_SL_JL) SUM_SL_JL,\nSUM(SUM_SL_DL) SUM_SL_DL,\nSUM(SUM_J_HL) SUM_J_HL,\nSUM(SUM_D_HL) SUM_D_HL,\nSUM(QCYE_HL) QCYE_HL,\nSUM(QMYE_HL) QMYE_HL";
    public static String SELECT_KEY_VALUE_FIELD_OUT_STA_CUR = "       ,SUM_J_BWB_YJZ\n       ,SUM_D_BWB_YJZ\n       ,SUM_JL_BWB_YJZ\n       ,SUM_DL_BWB_YJZ\n       ,SUM_J_BWB_WJZ\n       ,SUM_D_BWB_WJZ\n       ,QCYE_BWB_YJZ\n       ,QMYE_BWB_YJZ FROM";
    public static String SELECT_KEY_VALUE_FIELD_OUT_FOR_CUR = "       ,SUM_J_YJZ\n       ,SUM_J_BWB_YJZ\n       ,SUM_D_YJZ\n       ,SUM_D_BWB_YJZ\n       ,SUM_JL_YJZ\n       ,SUM_JL_BWB_YJZ\n       ,SUM_DL_YJZ\n       ,SUM_DL_BWB_YJZ\n       ,SUM_J_WJZ\n       ,SUM_J_BWB_WJZ\n       ,SUM_D_WJZ\n       ,SUM_D_BWB_WJZ\n       ,QCYE_YJZ\n       ,QCYE_BWB_YJZ\n       ,QMYE_YJZ\n       ,QMYE_BWB_YJZ FROM";
    public static String SELECT_KEY_VALUE_FIELD_IN_STA_CUR = "\t\t       ,SUM(SUM_J_BWB_YJZ) SUM_J_BWB_YJZ\n\t\t       ,SUM(SUM_D_BWB_YJZ) SUM_D_BWB_YJZ\n\t\t       ,SUM(SUM_JL_BWB_YJZ) SUM_JL_BWB_YJZ\n\t\t       ,SUM(SUM_DL_BWB_YJZ) SUM_DL_BWB_YJZ\n\t\t       ,SUM(SUM_J_BWB_WJZ) SUM_J_BWB_WJZ\n\t\t       ,SUM(SUM_D_BWB_WJZ) SUM_D_BWB_WJZ\n\t\t       ,ABS(SUM(QCYE_BWB_YJZ)) QCYE_BWB_YJZ\n\t\t       ,ABS(SUM(QMYE_BWB_YJZ)) QMYE_BWB_YJZ FROM";
    public static String SELECT_KEY_VALUE_FIELD_IN_FOR_CUR = "\t\t       ,SUM(SUM_J_YJZ) SUM_J_YJZ\n\t\t       ,SUM(SUM_J_BWB_YJZ) SUM_J_BWB_YJZ\n\t\t       ,SUM(SUM_D_YJZ) SUM_D_YJZ\n\t\t       ,SUM(SUM_D_BWB_YJZ) SUM_D_BWB_YJZ\n\t\t       ,SUM(SUM_JL_YJZ) SUM_JL_YJZ\n\t\t       ,SUM(SUM_JL_BWB_YJZ) SUM_JL_BWB_YJZ\n\t\t       ,SUM(SUM_DL_YJZ) SUM_DL_YJZ\n\t\t       ,SUM(SUM_DL_BWB_YJZ) SUM_DL_BWB_YJZ\n\t\t       ,SUM(SUM_J_WJZ) SUM_J_WJZ\n\t\t       ,SUM(SUM_J_BWB_WJZ) SUM_J_BWB_WJZ\n\t\t       ,SUM(SUM_D_WJZ) SUM_D_WJZ\n\t\t       ,SUM(SUM_D_BWB_WJZ) SUM_D_BWB_WJZ\n\t\t       ,ABS(SUM(QCYE_YJZ)) QCYE_YJZ \n\t\t       ,ABS(SUM(QCYE_BWB_YJZ)) QCYE_BWB_YJZ \n\t\t       ,ABS(SUM(QMYE_YJZ)) QMYE_YJZ \n\t\t       ,ABS(SUM(QMYE_BWB_YJZ)) QMYE_BWB_YJZ FROM";
    public static String SELECT_WD_MX_FIELD_STA_CUR = ",SUM(TWBMONEYF) SUM_J_BWB_YJZ,\nSUM(TNUM1F) SUM_D_BWB_YJZ,\nSUM(SUM_SL_D) SUM_JL_BWB_YJZ,\nSUM(SUM_SL_DL) SUM_DL_BWB_YJZ,\nSUM(SUM_D_HL) SUM_J_BWB_WJZ,\nSUM(QMYE_HL) SUM_D_BWB_WJZ,\nSUM(WD59) QCYE_BWB_YJZ,\nSUM(WD60) QMYE_BWB_YJZ FROM";
    public static String SELECT_WD_MX_FIELD_FOR_CUR = ",SUM(TMONEYF) SUM_J_YJZ,\nSUM(TWBMONEYF) SUM_J_BWB_YJZ,\nSUM(NUMSCALEF) SUM_D_YJZ,\nSUM(TNUM1F) SUM_D_BWB_YJZ,\nSUM(SUM_SL_J) SUM_JL_YJZ,\nSUM(SUM_SL_D) SUM_JL_BWB_YJZ,\nSUM(SUM_SL_JL) SUM_DL_YJZ,\nSUM(SUM_SL_DL) SUM_DL_BWB_YJZ ,\nSUM(SUM_J_HL) SUM_J_WJZ,\nSUM(SUM_D_HL) SUM_J_BWB_WJZ,\nSUM(QCYE_HL) SUM_D_WJZ,\nSUM(QMYE_HL) SUM_D_BWB_WJZ,\nSUM(WD59) QCYE_YJZ,\nSUM(WD29) QCYE_BWB_YJZ,\nSUM(WD60) QMYE_YJZ,\nSUM(WD30) QMYE_BWB_YJZ FROM\n";

    public AccComprehensiveQueryConvertSqlDao() {
    }

    public static String selectKeyValueSql(String sql, Map<String, Object> param) {
        int accoStatus = ConvertUtil.toInt(param.get("accoStatus"));
        if (accoStatus != 3) {
            return sql;
        } else {
            int isForCur = ConvertUtil.toInt(param.get("isForCur"));
            String hasWd = ConvertUtil.toString(param.get("wdCol"));
            byte count;
            if (StringUtils.isEmpty(hasWd)) {
                count = 2;
            } else {
                count = 3;
            }

            for(int i = 0; i <= count; ++i) {
                sql = sql.replaceFirst("FROM", "%s");
            }

            String result;
            if (count == 2) {
                if (isForCur == 1) {
                    result = String.format(sql, SELECT_KEY_VALUE_FIELD_OUT_FOR_CUR, SELECT_KEY_VALUE_FIELD_IN_FOR_CUR, SELECT_WD_MX_FIELD_FOR_CUR);
                } else {
                    result = String.format(sql, SELECT_KEY_VALUE_FIELD_OUT_STA_CUR, SELECT_KEY_VALUE_FIELD_IN_STA_CUR, SELECT_WD_MX_FIELD_STA_CUR);
                }
            } else if (isForCur == 1) {
                result = String.format(sql, SELECT_KEY_VALUE_FIELD_OUT_FOR_CUR, SELECT_KEY_VALUE_FIELD_IN_FOR_CUR, SELECT_WD_MX_FIELD_FOR_CUR, SELECT_WD_MX_FIELD_FOR_CUR);
            } else {
                result = String.format(sql, SELECT_KEY_VALUE_FIELD_OUT_STA_CUR, SELECT_KEY_VALUE_FIELD_IN_STA_CUR, SELECT_WD_MX_FIELD_STA_CUR, SELECT_WD_MX_FIELD_STA_CUR);
            }

            return result;
        }
    }

    public static String concatSql(String sql, Map<String, Object> param) {
        String fromSql = getSubSelectSql(sql, param);
        String result = sql.replace(fromSql, "%s");
        Map<Integer, String> sumSql = getConcatSql(fromSql);
        Map<Integer, String> splitSql = splitSql(fromSql);
        String selectField = (String)sumSql.get(2);
        String insertField = (String)sumSql.get(3);
        param.put("yjzInsertField", insertField);
        result = result.replace("FROM", selectField.concat("\n").concat(" FROM \n"));
        String wjzSql = String.format((String)splitSql.get(0), sumSql.get(0));
        String yjzSql = String.format((String)splitSql.get(1), sumSql.get(1));
        result = String.format(result, wjzSql.concat("\n UNION ALL \n").concat(yjzSql));
        param.put("yjzSelectSql", result);
        return result;
    }

    public static String unionConcatSql(String sql, Map<String, Object> param) {
        int accoStatus = ConvertUtil.toInt(param.get("accoStatus"));
        if (accoStatus != 3) {
            return sql;
        } else if (sql.contains("UNION ALL")) {
            String[] parts = sql.split("UNION ALL");
            String forCurSql = parts[0].trim();
            String staCurSql = parts[1].trim();
            String fromForCurSql = getSubSelectSql(forCurSql, param);
            String fromStaCurSql = getSubSelectSql(staCurSql, param);
            Map<Integer, String> sumSql = getConcatSql(fromForCurSql);
            String result = sql.replace(fromForCurSql, "%s");
            result = result.replace(fromStaCurSql, "%s");
            String selectField = (String)sumSql.get(2);
            String insertField = (String)sumSql.get(3);
            param.put("yjzInsertField", insertField);
            result = result.replace("FROM", selectField.concat("\n").concat(" FROM \n"));
            Map<Integer, String> splitForCurSql = splitSql(fromForCurSql);
            Map<Integer, String> splitStaCurSql = splitSql(fromStaCurSql);
            String wjzForCurSql = String.format((String)splitForCurSql.get(0), sumSql.get(0));
            String yjzForCurSql = String.format((String)splitForCurSql.get(1), sumSql.get(1));
            String wjzStaCurSql = String.format((String)splitStaCurSql.get(0), sumSql.get(0));
            String yjzStaCurSql = String.format((String)splitStaCurSql.get(1), sumSql.get(1));
            result = String.format(result, wjzForCurSql.concat("\n UNION ALL \n").concat(yjzForCurSql), wjzStaCurSql.concat("\n UNION ALL \n").concat(yjzStaCurSql));
            param.put("yjzSelectSql", result);
            return result;
        } else {
            return concatSql(sql, param);
        }
    }

    public static String convertInsertWdBillMxSql(String sql, Map<String, Object> param) {
        int accoStatus = ConvertUtil.toInt(param.get("accoStatus"));
        if (accoStatus != 3) {
            return sql;
        } else {
            String yjzSelectSql = ConvertUtil.toString(param.get("yjzSelectSql"));
            if (StringUtils.isNotEmpty(yjzSelectSql)) {
                Pattern pattern = Pattern.compile("(INSERT INTO GT_ZW_WDBILLMX \\(.*?\\))", 32);
                Matcher matcher = pattern.matcher(sql);
                if (matcher.find()) {
                    String insertFieldSql = matcher.group(1);
                    Pattern pattern2 = Pattern.compile("INSERT INTO GT_ZW_WDBILLMX \\((.*?)\\)", 32);
                    Matcher matcher2 = pattern2.matcher(insertFieldSql);
                    String fields;
                    if (matcher2.find()) {
                        fields = matcher2.group(1);
                        insertFieldSql = insertFieldSql.replace(fields, "%s");
                        String yjzInsertField = ConvertUtil.toString(param.get("yjzInsertField"));
                        String convertFields = fields;
                        if (!fields.contains(yjzInsertField)) {
                            convertFields = fields.concat(yjzInsertField);
                        }

                        insertFieldSql = String.format(insertFieldSql, convertFields);
                    }

                    fields = insertFieldSql.concat("\n").concat(yjzSelectSql);
                    return fields;
                }
            }

            return sql;
        }
    }

    public static String convertInsertWdBillMxQtSql(String sql, Map<String, Object> param) {
        int accoStatus = ConvertUtil.toInt(param.get("accoStatus"));
        if (accoStatus != 3) {
            return sql;
        } else {
            int isForCur = ConvertUtil.toInt(param.get("isForCur"));
            Pattern pattern = Pattern.compile("(INSERT INTO GT_ZW_WDBILLMX\\s*\\(.*?\\))", 32);
            Matcher matcher = pattern.matcher(sql);
            if (matcher.find()) {
                String insertFieldSql = matcher.group(1);
                String yjzSelectSql = sql.replace(insertFieldSql, "");
                Pattern pattern2 = Pattern.compile("\\((.*?)\\)", 32);
                Matcher matcher2 = pattern2.matcher(insertFieldSql);
                String yjzInsertSql;
                if (matcher2.find()) {
                    yjzInsertSql = matcher2.group(1);
                    insertFieldSql = insertFieldSql.replace(yjzInsertSql, "%s");
                    String convertFields;
                    if (isForCur == 1) {
                        convertFields = yjzInsertSql.concat(QT_INSERT_FOR_CUR_FIELD);
                    } else {
                        convertFields = yjzInsertSql.concat(QT_INSERT_STA_CUR_FIELD);
                    }

                    insertFieldSql = String.format(insertFieldSql, convertFields);
                }

                yjzSelectSql = yjzSelectSql.replace("FROM", " %s FROM");
                if (isForCur == 1) {
                    yjzSelectSql = String.format(yjzSelectSql, QT_SELECT_FOR_CUR_FIELD);
                } else {
                    yjzSelectSql = String.format(yjzSelectSql, QT_SELECT_STA_CUR_FIELD);
                }

                yjzInsertSql = insertFieldSql.concat("\n").concat(yjzSelectSql);
                return yjzInsertSql;
            } else {
                return sql;
            }
        }
    }

    private static String getSubSelectSql(String sql, Map<String, Object> param) {
        String hasWd = ConvertUtil.toString(param.get("wdCol"));
        if (StringUtils.isNotEmpty(hasWd)) {
            return sql;
        } else {
            String pattern = "FROM \\((.*?)\\) A1";
            Pattern r = Pattern.compile(pattern, 32);
            Matcher m = r.matcher(sql);
            if (m.find()) {
                return m.group(1);
            } else {
                throw new RuntimeException("getSubSelectSql is not font sql");
            }
        }
    }

    private static Map<String, String> parseSumExpressions(String sql) {
        Pattern pattern = Pattern.compile("SUM\\((.*?)\\)\\s(\\w+),");
        Matcher matcher = pattern.matcher(sql);
        Map<String, String> map = new LinkedHashMap();

        while(matcher.find()) {
            map.put(matcher.group(2), "SUM(" + matcher.group(1) + ")");
        }

        return map;
    }

    private static Map<String, String> parseSumExpressions2(String sql) {
        Map<String, String> result = new LinkedHashMap();
        Deque<Integer> stack = new ArrayDeque();

        for(int i = 0; i < sql.length(); ++i) {
            if (sql.charAt(i) == '(') {
                stack.push(i);
            } else if (sql.charAt(i) == ')') {
                int start = (Integer)stack.pop();
                if (stack.isEmpty()) {
                    int end;
                    for(end = i; i + 1 < sql.length() && Character.isWhitespace(sql.charAt(i + 1)); ++i) {
                    }

                    if (i + 1 < sql.length() && Character.isLetter(sql.charAt(i + 1))) {
                        int keyStart;
                        for(keyStart = i + 1; i + 1 < sql.length() && (Character.isLetter(sql.charAt(i + 1)) || sql.charAt(i + 1) == '_'); ++i) {
                        }

                        String key = sql.substring(keyStart, i + 1);
                        String value = sql.substring(start, end + 1);
                        result.put(key, "SUM(" + value + ")");
                    }
                }
            }
        }

        return result;
    }

    private static Map<Integer, String> getConcatSql(String sql) {
        Map<Integer, String> result = new HashMap();
        Map<String, String> map = parseSumExpressions2(sql);
        String yjzTemplateSql;
        String wjzTemplateSql;
        String selectField;
        String insertField;
        if (map.containsKey("SUM_J") && map.containsKey("SUM_J_BWB")) {
            yjzTemplateSql = " {SUM_J} SUM_J_YJZ, \n {SUM_J_BWB} SUM_J_BWB_YJZ, \n {SUM_D} SUM_D_YJZ, \n {SUM_D_BWB} SUM_D_BWB_YJZ, \n 0 SUM_J_WJZ, \n 0 SUM_J_BWB_WJZ, \n 0 SUM_D_WJZ, \n 0 SUM_D_BWB_WJZ, \n {SUM_JL} SUM_JL_YJZ, \n {SUM_JL_BWB} SUM_JL_BWB_YJZ, \n {SUM_DL} SUM_DL_YJZ, \n {SUM_DL_BWB} SUM_DL_BWB_YJZ, \n {QCYE} QCYE_YJZ, \n {QCYE_BWB} QCYE_BWB_YJZ, \n {QMYE} QMYE_YJZ, \n {QMYE_BWB} QMYE_BWB_YJZ \n";
            wjzTemplateSql = " 0 SUM_J_YJZ, \n 0 SUM_J_BWB_YJZ, \n 0 SUM_D_YJZ, \n 0 SUM_D_BWB_YJZ, \n {SUM_J} SUM_J_WJZ, \n {SUM_J_BWB} SUM_J_BWB_WJZ, \n {SUM_D} SUM_D_WJZ, \n {SUM_D_BWB} SUM_D_BWB_WJZ, \n 0 SUM_JL_YJZ, \n 0 SUM_JL_BWB_YJZ, \n 0 SUM_DL_YJZ, \n 0 SUM_DL_BWB_YJZ, \n 0 QCYE_YJZ, \n 0 QCYE_BWB_YJZ, \n 0 QMYE_YJZ, \n 0 QMYE_BWB_YJZ \n";
            selectField = "\t\t\t\t  /*已记账-借贷*/\n\t\t\t         ,A1.SUM_J_YJZ, \n\t\t\t\t       A1.SUM_J_BWB_YJZ,\n\t\t\t\t       A1.SUM_D_YJZ,\n\t\t\t\t       A1.SUM_D_BWB_YJZ,\n \t\t\t\t      /*已记账-累计*/\n\t\t\t\t       A1.SUM_JL_YJZ,\n\t\t\t\t       A1.SUM_JL_BWB_YJZ,\n\t\t\t\t       A1.SUM_DL_YJZ,\n\t\t\t\t       A1.SUM_DL_BWB_YJZ,\n\t\t\t\t        /*未记账-借贷*/\n\t\t\t\t       A1.SUM_J_WJZ, \n\t\t\t\t       A1.SUM_J_BWB_WJZ,\n\t\t\t\t       A1.SUM_D_WJZ, \n\t\t\t\t       A1.SUM_D_BWB_WJZ, \n\t\t\t\t       A1.QCYE_YJZ,\n\t\t\t\t       A1.QCYE_BWB_YJZ,\n\t\t\t\t       A1.QMYE_YJZ,\n\t\t\t\t       A1.QMYE_BWB_YJZ\n";
            insertField = ",TMONEYF,\nTWBMONEYF,\nNUMSCALEF,\nTNUM1F,\nSUM_SL_J,\nSUM_SL_D,\nSUM_SL_JL,\nSUM_SL_DL,\nSUM_J_HL,\nSUM_D_HL,\nQCYE_HL,\nQMYE_HL,\nWD59,\nWD29,\nWD60,\nWD30\n";
        } else {
            yjzTemplateSql = " {SUM_J_BWB} SUM_J_BWB_YJZ, \n {SUM_D_BWB} SUM_D_BWB_YJZ, \n 0 SUM_J_BWB_WJZ, \n 0 SUM_D_BWB_WJZ, \n {SUM_JL_BWB} SUM_JL_BWB_YJZ, \n {SUM_DL_BWB} SUM_DL_BWB_YJZ, \n {QCYE_BWB} QCYE_BWB_YJZ, \n {QMYE_BWB} QMYE_BWB_YJZ \n";
            wjzTemplateSql = " 0 SUM_J_BWB_YJZ, \n 0 SUM_D_BWB_YJZ, \n {SUM_J_BWB} SUM_J_BWB_WJZ, \n {SUM_D_BWB} SUM_D_BWB_WJZ, \n 0 SUM_JL_BWB_YJZ, \n 0 SUM_DL_BWB_YJZ, \n 0 QCYE_BWB_YJZ, \n 0 QMYE_BWB_YJZ \n";
            selectField = "\t\t\t\t  /*已记账-借贷*/\n\t\t\t\t       ,A1.SUM_J_BWB_YJZ,\n\t\t\t\t       A1.SUM_D_BWB_YJZ,\n \t\t\t\t      /*已记账-累计*/\n\t\t\t\t       A1.SUM_JL_BWB_YJZ,\n\t\t\t\t       A1.SUM_DL_BWB_YJZ,\n\t\t\t\t        /*未记账-借贷*/\n\t\t\t\t       A1.SUM_J_BWB_WJZ,\n\t\t\t\t       A1.SUM_D_BWB_WJZ,\n\t\t\t\t       A1.QCYE_BWB_YJZ,\n\t\t\t\t       A1.QMYE_BWB_YJZ\n";
            insertField = "\n,TWBMONEYF,\nTNUM1F,\nSUM_SL_D,\nSUM_SL_DL,\nSUM_D_HL,\nQMYE_HL,\nWD59,\nWD60\n";
        }

        Map.Entry entry;
        for(Iterator var7 = map.entrySet().iterator(); var7.hasNext(); yjzTemplateSql = yjzTemplateSql.replace("{" + (String)entry.getKey() + "}", (CharSequence)entry.getValue())) {
            entry = (Map.Entry)var7.next();
            wjzTemplateSql = wjzTemplateSql.replace("{" + (String)entry.getKey() + "}", (CharSequence)entry.getValue());
        }

        result.put(0, wjzTemplateSql);
        result.put(1, yjzTemplateSql);
        result.put(2, selectField);
        result.put(3, insertField);
        return result;
    }

    private static Map<Integer, String> splitSql(String sql) {
        Map<Integer, String> result = new HashMap();
        String yjzSql = sql.replace("GROUP BY", "AND A.ENTRY_MARK = 1 \n GROUP BY");
        yjzSql = yjzSql.replaceFirst("FROM", "\n ,%s FROM ");
        result.put(1, yjzSql);
        String wjzSql = sql.replaceFirst("FROM", "\n ,%s FROM ");
        wjzSql = wjzSql.replace("GROUP BY", "AND A.ENTRY_MARK = 0 \n GROUP BY");
        result.put(0, wjzSql);
        return result;
    }

    public static String convertSqlToSupportXjmxOrHzDataForIsShowAllWd(String sql, Map<String, Object> param) {
        String wdCol = ConvertUtil.toString(param.get("wdCol"));
        boolean isShowAllWd = ConvertUtil.toBoolean(param.get("isShowAllWd"));
        boolean isxjmx = ConvertUtil.toBoolean(param.get("xjmx"));
        if (isShowAllWd || isxjmx) {
            if (StringUtils.isNotEmpty(wdCol)) {
                String pattern = "GT_KMDESTTAB A,(.*?) B\n";
                Pattern r = Pattern.compile(pattern, 32);
                Matcher m = r.matcher(sql);
                if (m.find()) {
                    String extractedSql = m.group(1);
                    String tempSql = sql.replace(extractedSql, "%s");
                    String formateSql = getMergeSql(extractedSql, param);
                    sql = String.format(tempSql, formateSql);
                    if (isShowAllWd) {
                        sql = sql.replace("AND A.LEAF = 1  AND A.STOPED = 0 ", "AND A.STOPED = 0 ");
                    }
                }
            } else if (sql.contains(",BZRED")) {
                sql = sql.replace(",BZRED", "");
                sql = sql.replace(" AND (A.LEAF = 0 AND BZRED = 0) OR (A.LEAF <> 0) ", "");
            }
        }

        return sql;
    }

    private static String getSql(String sql) {
        int start = sql.indexOf("(");
        int end = sql.lastIndexOf(")");
        if (start != -1 && end != -1) {
            sql = sql.substring(start + 1, end);
        }

        return sql;
    }

    private static String getRedSql(String sql, Map<String, Object> param) {
        String wdCol = ConvertUtil.toString(param.get("wdCol"));
        String selectField = wdCol.concat(", 2 BZRED");
        String newSql = sql.replace(wdCol, "%s ");
        newSql = String.format(newSql, selectField, wdCol);
        return newSql;
    }

    private static String getKmMergeSql(String sql, Map<String, Object> param) {
        String wdCol = ConvertUtil.toString(param.get("wdCol"));
        String newSql = sql.replace(wdCol, "%s\n");
        String wdNullCol = wdCol.replace(",", ", NULL AS");
        wdNullCol = wdNullCol.concat(", 0 BZRED");
        newSql = String.format(newSql, wdNullCol, "");
        return newSql;
    }

    private static String getWdMergeSql(String sql, Map<String, Object> param) {
        boolean levelDetails = ConvertUtil.toBoolean(param.get("levelDetails"));
        String wdCol = ConvertUtil.toString(param.get("wdCol"));
        String wdNewCol = wdCol.replaceFirst(",", "");
        List<String> wdList = (List)Arrays.stream(wdNewCol.split(",")).map(String::trim).collect(Collectors.toList());
        List<Map<String, Object>> selectWds = (List)param.get("xjmxSelectWd");
        Stream var10000 = selectWds.stream().map((e) -> {
            return (String)e.get("wdname");
        });
        wdList.getClass();
        String groupField = (String)var10000.filter(wdList::contains).collect(Collectors.joining(","));
        if (StringUtils.isEmpty(groupField)) {
            return null;
        } else {
            StringBuilder sb = new StringBuilder();
            Iterator var10 = wdList.iterator();

            String selectField;
            while(var10.hasNext()) {
                selectField = (String)var10.next();
                if (groupField.contains(selectField)) {
                    sb.append(selectField).append(",");
                } else {
                    sb.append(" NULL AS ").append(selectField).append(",");
                }
            }

            String output = sb.toString().replaceAll(",$", "");
            selectField = output.concat(", 1 BZRED");
            String replaceField;
            String firstWd;
            if (levelDetails) {
                if (selectWds.size() == wdList.size()) {
                    param.put("levelDetailsIsSame", true);
                }

                firstWd = groupField.split(",")[0];
                String levelRollUpWdCol;
                if (DBUtil.isMySql()) {
                    levelRollUpWdCol = groupField + " WITH ROLLUP  HAVING  " + firstWd + " IS NOT NULL ";
                } else {
                    levelRollUpWdCol = " ROLLUP(" + wdCol.substring(1) + ") HAVING  " + firstWd + " IS NOT NULL ";
                }

                replaceField = levelRollUpWdCol;
            } else {
                if (selectWds.size() == wdList.size()) {
                    return null;
                }

                replaceField = groupField;
            }

            firstWd = sql.replace(wdCol, ",%s ");
            firstWd = String.format(firstWd, selectField, replaceField);
            return firstWd;
        }
    }

    private static String getMergeSql(String sql, Map<String, Object> param) {
        StringBuilder resultSql = new StringBuilder("(");
        String newSql = getSql(sql);
        String redSql = getRedSql(newSql, param);
        String kmSql = getKmMergeSql(newSql, param);
        String wdSql = getWdMergeSql(newSql, param);
        if (StringUtils.isNotEmpty(wdSql)) {
            if (ConvertUtil.toBoolean(param.get("levelDetailsIsSame"))) {
                resultSql.append(kmSql).append("\n UNION ALL \n").append(wdSql).append(")");
            } else {
                resultSql.append(kmSql).append("\n UNION ALL \n").append(wdSql).append("\n UNION ALL \n").append(redSql).append(")");
            }
        } else {
            resultSql.append(kmSql).append("\n UNION ALL \n").append(redSql).append(")");
        }

        return resultSql.toString();
    }

    public static void changeListOrder(Map<String, Object> param) {
        List<Map<String, Object>> xjmxSelectWds = (List)param.get("xjmxSelectWd");
        List<Map> dimTypeList = (List)param.get("subjectCacMap");
        if (!CollectionUtils.isEmpty(xjmxSelectWds) && !CollectionUtils.isEmpty(dimTypeList)) {
            List<String> orderList = (List)xjmxSelectWds.stream().map((e) -> {
                return (String)e.get("lxid");
            }).collect(Collectors.toList());
            OptionalInt maxIndex = dimTypeList.stream().map((e) -> {
                return orderList.indexOf((String)e.get("dim_type_id"));
            }).mapToInt(Integer::intValue).max();
            int maxIndexValue = maxIndex.orElse(0);
            dimTypeList.sort(Comparator.comparingInt((m) -> {
                int sort = orderList.indexOf((String)m.get("dim_type_id"));
                if (sort == -1) {
                    sort = maxIndexValue + 1;
                }

                return sort;
            }));
            param.put("subjectCacMap", dimTypeList);
        }

    }

    public static String changeBeginBalanceSomeInfo(String sql, Map<String, Object> param) {
        Map<String, Object> beginBalanceParam = (Map)param.get("beginBalanceParam");
        if (!Objects.isNull(beginBalanceParam) && !beginBalanceParam.isEmpty()) {
            sql = sql.replace("QCFX, QCYE,QCYE_BWB", "QCFX_NC,QCYE_NC,QCYE_BWB_NC,QCFX, QCYE,QCYE_BWB");
            sql = sql.replace("QCFX, QCYE_BWB", "QCFX_NC, QCYE_BWB_NC,QCFX, QCYE_BWB");
            if (DBUtil.isMySql()) {
                sql = sql.replace("(CASE SIGN(SUM(QCYE_BWB))  WHEN 1 THEN  '借' WHEN -1 THEN '贷' ELSE '-' END) QCFX", "(CASE SIGN(SUM(QCYE_BWB))  WHEN 1 THEN  '借' WHEN -1 THEN '贷' ELSE '-' END) QCFX, (CASE SIGN(SUM(QCYE_BWB_NC))  WHEN 1 THEN  '借' WHEN -1 THEN '贷' ELSE '-' END) QCFX_NC");
            } else {
                sql = sql.replace("DECODE(SIGN(SUM(QCYE_BWB)), 1, '借', -1, '贷', '-') QCFX", "DECODE(SIGN(SUM(QCYE_BWB)), 1, '借', -1, '贷', '-') QCFX,DECODE(SIGN(SUM(QCYE_BWB_NC)), 1, '借', -1, '贷', '-') QCFX_NC");
            }

            sql = sql.replace("ABS(SUM(QCYE)) QCYE", "ABS(SUM(QCYE)) QCYE,ABS(SUM(QCYE_NC)) QCYE_NC");
            sql = sql.replace("ABS(SUM(QCYE_BWB)) QCYE_BWB", "ABS(SUM(QCYE_BWB)) QCYE_BWB, ABS(SUM(QCYE_BWB_NC)) QCYE_BWB_NC");
        }

        return sql;
    }
}
